// 封装axios的通用请求方法

// 导入axios
import axios from 'axios'
// 导入element-plus的消息提示方法
import { ElMessage } from 'element-plus'
import router from '@/router'
//声明基础url
const requestURL = "http://localhost:8080"
// const requestURL = "/api"

// 创建axios实例
const axiosInstance = axios.create({
    //创建时指定默认的baseURL   使用时可以不用指定(拼接)
    baseURL: requestURL,
    // 请求超时时间   
    timeout: 5000
})


//前端在发送请求时，需要确保正确设置了 withCredentials 属性，以允许携带跨域请求的凭证（如 Cookie、HTTP 认证等）
axios.defaults.withCredentials = true;

//请求前的处理逻辑
//axios拦截器  interceptors
//作用相当于过滤器  

// 定义不需要验证 token 的接口路径
const noAuthPaths = ['/login', '/register'];
// 请求拦截器
axiosInstance.interceptors.request.use(
    config => {
        //给每个请求添加token
        const token = localStorage.getItem('token');
        if (token) {
            config.headers['authorization'] = `Bearer ${token}`;
        }
        return config
    },
    error => {
        // 对请求错误的处理逻辑：跳转到登录页面
        return Promise.reject(error)
    }
)


//请求后的处理逻辑
// 响应拦截器
axiosInstance.interceptors.response.use(
    res => {
        // 对响应数据的处理逻辑
        // 后端返回的数据封装为了JsonResult，这里需要取出data
        if(res.data.code === 401||res.data.code === 50001||res.data.code === 50002||res.data.code === 50003){
            ElMessage({ message: res.data.msg, duration: 1500 });
             // 未授权，跳转到登录页面
             localStorage.removeItem('token');
             router.push('/');
        }
        return res.data
    },
    // error的集中处理 
    (error) => {
        const status: number = error.response.status
        switch (status) {
            case 400:
                ElMessage({ message: error.response.data.msg, duration: 1500 });
                break;
            case 401:
                ElMessage({ message: "没有权限访问", duration: 1500 });
                // 未授权，跳转到登录页面
                sessionStorage.removeItem('token');
                router.push('/');
                //window.location.href = '/';
                break;
            case 404:
                ElMessage({ message: "接口不存在或者请求方式不对", duration: 1500 });
                break;
            case 500:
                ElMessage({ message: "服务器请求失败", duration: 1500 });
                break;
            default:
                ElMessage({ message: "未知错误", duration: 1500 });
        }
        return Promise.reject(error)
    }
)

// 封装统一的返回数据类型，使用泛型T作为data的类型
// 使用了export，导出了这个接口   其他文件中就可导入使用
export interface ApiResponse<T> {
    code: number
    msg: string
    data: T
}




//请求发生
//axios发送请求中get和post的区别
/*
制定一个规范
1、执行查询查找使用get请求（getParameter()）
2、执行 添加修改删除 使用post请求(json字符串) 
3、特殊查询请求（包含敏感字段，如密码），也使用post请求
*/

// 封装通用get请求方法
export const get = <T>(url: string, params?: object): Promise<ApiResponse<T>> => {
    //在使用时，必须带大括号，并且以参数形式params
    return axiosInstance.get(url, { params })
}

// 封装通用post请求方法
export const post = <T>(url: string, data?: object, config?: any): Promise<ApiResponse<T>> => {
    //封装的时候，直接将所有的post请求都封装为json字符串，后端接收到时，直接转为对象
    //所以后端不能直接使用字段接收
    return axiosInstance.post(url, data, config)
}

// 封装通用put请求方法
export const put = <T>(url: string, data?: object, config?: any): Promise<ApiResponse<T>> => {
    return axiosInstance.put(url,data,config)
}

// 封装通用delete请求方法
export const del = <T>(url: string, config?: any): Promise<ApiResponse<T>> => {
    return axiosInstance.delete(url,config)
}

